﻿// owner 蒋家伟

#include "ObjectReflectUnitTest.h"

// jsdk
#include "UnitTestDataDefine.h"
#include "UnitTestUtils.h"
#include "Dbg_Warn_Define.h"

// schema反射所需要的四个头文件
#include "ObjectReflectDefine.h"
#include "ObjectClassDefine.h"

using namespace std;
using namespace jsdk;

namespace jsdk
{
    class TestC : public DBSchemaObject
    {
    public:
        static const UniqueId& getReflectUid() {
            static UniqueId s_TestC_UID = UniqueId::fromWString(L"{2E160D53-DF9A-4B4A-B068-DC57316FB6AD}");
            return s_TestC_UID;
        };
        virtual const std::wstring& getTestString() const  { return m_wstringTest; };
        virtual const int getTestInt() const  { return m_intTest; };
        virtual const IElement* getTopLevelElement() const override { return nullptr; };

    private:
        int m_intTest = 3;
        std::wstring m_wstringTest = L"Test3";
    };
}

UNIT_TEST_START(jsdk, ObjectReflectUnitTest)
{
    ObjectReflectUnitTest test;
    bool success = test.testReflectObject();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(success, L"通过uid反射对象失败", L"蒋家伟", L"2023-11-13");

    success = test.testFieldReflect();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(success, L"字段反射失败", L"蒋家伟", L"2023-11-13");

    return true;
}

bool jsdk::ObjectReflectUnitTest::testReflectObject() const
{
    OwnerPtr<TestA> opTestA = ObjectReflectUtils::getObjectReflect<TestA>();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(opTestA, UnitTestUtils::combineErrorTestMsg(false, true, L"用TestA的uid反射TestA对象"), L"蒋家伟", L"2023-11-13");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(opTestA->getTestInt() == 0, UnitTestUtils::combineErrorTestMsg(opTestA->getTestInt(), 0, L"TestA对象的整形值"), L"蒋家伟", L"2023-11-13");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(opTestA->getTestString() == L"TestA", UnitTestUtils::combineErrorTestMsg(opTestA->getTestString(), L"TestA", L"TestA对象的字符串"), L"蒋家伟", L"2023-11-13");

    OwnerPtr<TestC> opTestC = ObjectReflectUtils::getObjectReflect<TestC>();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(opTestC == nullptr, UnitTestUtils::combineErrorTestMsg(true, false, L"用TestC的uid反射TestC对象没有注册但是反射成功"), L"蒋家伟", L"2023-11-13");
    return true;
}

bool jsdk::ObjectReflectUnitTest::testFieldReflect() const
{
    OwnerPtr<TestA> opTestA = ObjectReflectUtils::getObjectReflect<TestA>();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(opTestA, UnitTestUtils::combineErrorTestMsg(false, true, L"用TestA的uid反射TestA对象"), L"蒋家伟", L"2023-11-13");
    IFieldReflectManager* pFieldReflectManager = opTestA->getFieldReflectManager();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pFieldReflectManager, UnitTestUtils::combineErrorTestMsg(false, true, L"获取字段反射管理器失败"), L"蒋家伟", L"2023-11-13");
    IClassFieldDescriptor* pClassFieldDescriptor = pFieldReflectManager->getFieldDescriptor(L"");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pClassFieldDescriptor == nullptr, UnitTestUtils::combineErrorTestMsg(true, false, L"获取空字段应该失败"), L"蒋家伟", L"2023-11-13");
    pClassFieldDescriptor = pFieldReflectManager->getFieldDescriptor(L"IntTest");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pClassFieldDescriptor, UnitTestUtils::combineErrorTestMsg(false, true, L"获取IntTest字段应该成功"), L"蒋家伟", L"2023-11-13");
    int testA_int_reflect = *pClassFieldDescriptor->get<int>();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(opTestA->getTestInt() == testA_int_reflect, UnitTestUtils::combineErrorTestMsg(false, true, L"通过反射获取数据与成员函数调用"), L"蒋家伟", L"2023-11-13");
    pClassFieldDescriptor->set(10);
    testA_int_reflect = *pClassFieldDescriptor->get<int>();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(opTestA->getTestInt() == testA_int_reflect, UnitTestUtils::combineErrorTestMsg(false, true, L"通过反射获取数据与成员函数调用"), L"蒋家伟", L"2023-11-13");

    OwnerPtr<TestB> opTestB = ObjectReflectUtils::getObjectReflect<TestB>();
    //ownptr右值测试
    opTestB->setopITestATest(NEW_AS_OWNERPTR(TestA, L"测试子对象A", 0));
    pClassFieldDescriptor = opTestB->getFieldReflectManager()->getFieldDescriptor(L"opITestATest");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pClassFieldDescriptor, UnitTestUtils::combineErrorTestMsg(false, true, L"获取opTestATest字段应该成功"), L"蒋家伟", L"2023-11-13");
    DBG_WARN_AND_RETURN_FALSE_UNLESS(*(*pClassFieldDescriptor->get<OwnerPtr<ITestA>>()) == *(opTestB->getopITestATest()), UnitTestUtils::combineErrorTestMsg(false, true, L"通过反射获取数据与成员函数调用"), L"蒋家伟", L"2023-11-13");
    try
    {
        // 由于类型不正确，存储类型Ownptr<ITest> 设置的为Test，因此设置失败,内部设置失败会抛出异常需要注意
        pClassFieldDescriptor->set(NEW_AS_OWNERPTR(TestA, L"测试子对象A", 1));
    }
    catch(...){
        DBG_WARN_AND_RETURN_FALSE_UNLESS(!(*(NEW_AS_OWNERPTR(TestA, L"测试子对象A", 1)) == *(opTestB->getopITestATest())), UnitTestUtils::combineErrorTestMsg(false, true, L"通过反射获取数据与成员函数调用"), L"蒋家伟", L"2023-11-13");
    };

    pClassFieldDescriptor->set(jsdk::transformOwnerShipAndCast<DBSchemaObject>(transformOwnerShip(NEW_AS_OWNERPTR(TestA, L"测试子对象A", 2))));
    DBG_WARN_AND_RETURN_FALSE_UNLESS((*(NEW_AS_OWNERPTR(TestA, L"测试子对象A", 2)) == *(opTestB->getopITestATest())), UnitTestUtils::combineErrorTestMsg(false, true, L"通过反射获取数据与成员函数调用"), L"蒋家伟", L"2023-11-13");
    return true;
}

